import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { APIBase, ListOption } from 'app/modules/base/api-base';
import { toTree } from 'app/modules/share/components/tree/tree.component';
import { Observer, Observable, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class ZoneService extends APIBase<ZoneModel, Zone> {
  private url = 'api/admin/area';

  // private url = 'api/admin/batch_areas';
  constructor(protected http: HttpClient) {
    super(http, 'api/admin/area');
    // super(http, 'api/admin/batch_areas');
  }
  dataZones$ = new Subject()
  searchData$ = new Subject();
  tree$ = new Subject();

  get(id: number) {
    return super.get<ZoneDetail>(id);
  }

  batch_areas() {
    return new Observable((observer: Observer<any>) => {
      this.http.get('api/admin/batch_areas').subscribe((res) => {
        observer.next(res);
        observer.complete();
      });
    }).toPromise();
  }
  tree() {
    return super.list().then((result) => toTree(result.list, 'level_struct'));
  }

  resource<W, R>(zid: number, resource: ZoneResource) {
    // console.log(resource);
    return new APIBase<W, R>(this.http, `${this.url}/${zid}/${resource}`);
  }

  async getSceneConfig(zid: number) {
    let res=await this.http.get<SceneConfig>(`/api/admin/scene_config/${zid}`).toPromise();
    // console.log('res---:',res)
    let row=res.message[0]

    let pc_config=JSON.parse(row.pc_config);
                    let s=pc_config.script.content;
                    if(typeof(s)=='string' && s.trim().startsWith('blob:')){
                        // alert('fuck')
                        pc_config.script.content=''
                    }

                    row.pc_config=JSON.stringify(pc_config)

                    res.message[0]=row;

    return res;
  }

  getAreaScene(zid: number) {
    return this.http.get<ZoneScene>(`/api/admin/scenes/${zid}`).toPromise();
  }

  getConfig(zid: number, pcId?: number, userId?: number) {
    if (pcId && userId) {
      return this.http
        .get<BasicConfig>(`${this.url}/${zid}/user/${userId}/pc/${pcId}/config`)
        .toPromise();
    } else {
      return this.http.get<BasicConfig>(`${this.url}/${zid}/pc_config`).toPromise();
    }
  }

  setConfig(zid: number, formData: FormData) {
    return this.http.patch(`/api/admin/scene_config/${zid}`, formData).toPromise();
  }

  auth<R = any, W = any>(zid: number, resource: ZoneResource, path: [ZoneResource, number][]) {
    // user和pc查询，始终user在前
    if (path.length == 2 && path[0][0] == 'pc' && path[1][0] == 'user') {
      [path[1], path[0]] = [...path];
    }
    const url = path.reduce((p, r) => `${p}/${r[0]}/${r[1]}`, 'auth');
    return new APIBase<W, R>(this.http, `${this.url}/${zid}/${url}/${resource}`);
  }

  exec(zid: number) {
    return this.http.get(`${this.url}/${zid}/auth/exec`).toPromise();
  }
}
export interface ZoneModel {
  id?: 0;
  name: '';
  desc: '';
}
export interface Zone {
  id?: number;
  level_struct?: string;
  name?: string;
  des?: string;
  user_count?: number;
  pc_count?: number;
  software_count?: number;
  children?: Zone[];
  area_id?: number;
  checked?: boolean;
  fname?: string
  grade?: number
  had_child?: number
  loading?: false
  parent_id?: number
  trees?: string
}
export interface ZoneDetail extends Zone {
  id: number;
  name: string;
  parent_area_name: string;
  des: string;
  create_admin_username: string;
  created_at: string;
  user_count: number;
  new_user_count: number;
  pc_count: number;
  new_pc_count: number;
  software_count: number;
  new_software_count: number;
  auth_status: number;
}

export type ZoneResource = 'user' | 'pc' | 'software';
export interface ZonePersonnel {
  id: number;
  user_id: number;
  utype: number;
  full_name: string;
}
export interface ZoneComputer {
  id: number;
  pc_id: number;
  name: string;
}
export interface ZoneSoftware {
  id: number;
  software_id: number;
  name: string;
  version: string;
}

export enum ChooseScope {
  unselected,
  selected,
}
export interface ChooseListOption extends ListOption {
  scope: ChooseScope;
}

export interface ZoneComputerConfig {
  code: number;
  message: {
    basic_setting_config: BasicConfig;
    sys_setting_config: AppSetting[];
    sys_software_config: Software[];
  };
}

export interface BasicConfig {
  iptables: Iptables;
  screensaver: Screensaver;
  screensaver_file_path: ScreensaverFilePath,
  power: Power;
  pam_cracklib: Pamcracklib;
  wallpaper: Wallpaper;
  script: Script;
  can_login: boolean;
  clock_sync_config: ClockConfig;
}

export interface AppSetting {
  cn_name: string;
  disable_script: string;
  display_order: number;
  en_name: string;
  enable_script: string;
  group_name: string;
  setting_id: number;
  tool_tip: string;
  whether_enable: number;
  options: string;
  checked_option: string;
  template: number;
  relations_keys: string;
}

export interface Software {
  app_id: number;
  clip_script: string;
  display_order: number;
  package_name: string;
  rec_script: string;
  title: string;
  whether_clip: number;
}

export interface ZoneScene {
  code: number;
  message: {
    scene_name: string;
    scene_code: string;
    sort: number;
  };
}

export interface SceneConfig {
  code: number;
  message: {
    can_edit: number;
    full_zone_fix_html: string;
    full_zone_fix_url: string;
    full_zone_fix_html_name: string;
    full_zone_switch: 0;
    full_zone_verify_script: string;
    full_zone_verify_script_name: string;
    limit_policy: number;
    limit_software: string;
    pc_config: string;
    clock_sync_config: string;
    repair_zone_iptables: string;
    scene_code: string;
    sys_setting_config: string;
    sys_software_config: string;
  }[];
}

interface Script {
  name: string;
  content: string;
}
interface ScreensaverFilePath {
  name: string;
  content: string;
}

interface Wallpaper {
  image: string;
}

interface Pamcracklib {
  minlen: number;
  reject_username: boolean;
  minclass: number;
}

interface Power {
  display_standby: number;
}

interface Screensaver {
  enable: boolean;
  delay: number;
  screensaver_file_path: string
}

interface Iptables {
  content?: any;
}

interface ClockConfig {
  sync_switch: number;
  checked_period: number;
  checked_period_unit:any;
  ntp_server: string;
}
